using System;
using System.Windows.Forms;
using System.Collections.Generic;

using TD.SandDock;

using SBPweb.Contracts;
using SBPweb.Localization;

using SBPweb.Modules.Smartparts;
using SBPweb.Modules.Modularity;

using SBPweb.Controls.Windows.Docking;

using SBPweb.Presentation.Windows.Forms.Controls;
using SBPweb.Contracts.Implementation;

namespace SBPweb.Presentation.Windows.Forms.Controls
{

    public class DockManagerControl : SmartpartListBase<ISmartpart>
    {

        #region Private fields

		private const string cName = "SBPweb.Presentation.Windows.Forms.Host.Controls.DockManager";

		private PersistableDictionary pGuidPersistency;
		private IPersistable pParentPersistable;
		private ModuleLoader mLoader;
		private Control mParentControl;
		private DockManager pDockManager;

		private ToolStripMenuItem pWindowMenuItem;
        private ToolStripMenuItem pWindowsMenuItem;
        private ToolStripMenuItem pLayoutsMenuItem;
        
		private Dictionary<object, DockControl> pDockControlDictionary;
		private List<DockControl> pDisposingControls;
        private Dictionary<string, ISmartpart> pModalSmartpartDictionary;
		private ModalUserControl mModalUserControl;

		private MenuItemControl tsmiShowAll;
		private MenuItemControl tsmiHideAll;
		private MenuItemControl tsmiSaveCurrent;
		private MenuItemControl tsmiSaveAs;
		private MenuItemControl tsmiDelete;
		private MenuItemControl tsmiRename;
		private ToolStripSeparator tsmiSeparator;

		private LayoutNamingForm lnf = new LayoutNamingForm();
		private LayoutSelectForm lsf = new LayoutSelectForm();

        #endregion

        #region Constructor logic

        public DockManagerControl(Control parentControl, ModuleLoader loader, ToolStripMenuItem windowMenuItem, IPersistable parentPersistable)
        {

			pParentPersistable = parentPersistable;
			mLoader = loader;
            mParentControl = parentControl;

			#region DockManager

			pDockManager = new DockManager();
            pDockManager.OwnerForm = parentControl.FindForm();
            pDockManager.DockSystemContainer = parentControl;
            pDockManager.SerializeTabbedDocuments = true;

            pDockControlDictionary = new Dictionary<object, DockControl>();
			pDisposingControls = new List<DockControl>();
            pModalSmartpartDictionary = new Dictionary<string, ISmartpart>();

			pGuidPersistency = new PersistableDictionary("Guids", null, mLoader.Services.Get<IStatePersistenceService>());
			pGuidPersistency.LoadPersistency();

			#endregion

			#region Initialitze Window Menu

			if (windowMenuItem == null)
			{
				pWindowMenuItem = new MenuItemControl();
				pWindowMenuItem.Name = "pWindowMenuItem";
				pWindowMenuItem.Text = LocalizationExtender.GetString("pWindowMenuItemText");
				pWindowMenuItem.Image = Properties.Resources.Window.ToBitmap();
				pWindowMenuItem.ImageScaling = ToolStripItemImageScaling.None;
			}
			else
			{
				pWindowMenuItem = windowMenuItem;
			}

			tsmiShowAll = new MenuItemControl();
			tsmiShowAll.Name = "tsmiShowAll";
			tsmiShowAll.Text = LocalizationExtender.GetString("tsmiShowAllText");
			tsmiShowAll.Click += new EventHandler(tsmiShowAll_Click);

			tsmiHideAll = new MenuItemControl();
			tsmiHideAll.Name = "tsmiHideAll";
			tsmiHideAll.Text = LocalizationExtender.GetString("tsmiHideAllText");
			tsmiHideAll.Click += new EventHandler(tsmiHideAll_Click);

			pWindowsMenuItem = new MenuItemControl();
			pWindowsMenuItem.Name = "pWindowsMenuItem";
			pWindowsMenuItem.Text = LocalizationExtender.GetString("pWindowsMenuItemText");

			pWindowMenuItem.DropDown.Items.Add(tsmiShowAll);
			pWindowMenuItem.DropDown.Items.Add(tsmiHideAll);
			pWindowMenuItem.DropDown.Items.Add(new ToolStripSeparator());
			pWindowMenuItem.DropDown.Items.Add(pWindowsMenuItem);

			#endregion

			#region Events

			pDockManager.DockControlAdded += new DockControlEventHandler(pDockManager_DockControlAdded);
			pDockManager.DockControlRemoved += new DockControlEventHandler(pDockManager_DockControlRemoved);

			this.ItemAdded += new EventHandler<SmartpartEventArgs>(DockManagerControl_ItemAdded);
			this.ItemRemoved += new EventHandler<SmartpartEventArgs>(DockManagerControl_ItemRemoved);
			LocalizationExtender.OnInvalidatingControls += new EventHandler(LocalizationExtender_OnInvalidatingControls);

			if (LayoutService != null)
			{
				LayoutService.Initialized += new EventHandler(LayoutService_Initialized);
				LayoutService.Terminated +=new EventHandler(LayoutService_Finalized);
				LayoutService.LayoutLoaded += new EventHandler(LayoutService_LayoutLoaded);
				LayoutService.LayoutLoading += new EventHandler(LayoutService_LayoutLoading);
			}

			#endregion

		}

		public void Finalize()
		{
			if (pGuidPersistency != null)
			{
				pGuidPersistency.SavePersistency();
			}
			if (LayoutService != null)
			{
				LayoutService.Terminate();
			}
		}

        #endregion

        #region Property accessors

		public DockManager DockingManager
        {
            get
            {
                return pDockManager;
            }
        }

        public ToolStripMenuItem WindowMenu
        {
            get
            {
                return pWindowMenuItem;
            }
        }

        public string Name
        {
            get
            {
                return cName;
            }
        }

        public IModule Module
        {
            get
            {
                return null;
            }
        }

		public ILayoutService LayoutService
		{
			get
			{
				return mLoader.Services.Get<ILayoutService>();
			}
		}

        #endregion

        #region Event handlers

		#region Smartpart Handling

		protected void DockManagerControl_ItemAdded(object sender, SmartpartEventArgs e)
        {
            if (mParentControl != null && mParentControl.InvokeRequired)
            {
                mParentControl.Invoke(new EventHandler<SmartpartEventArgs>(DockManagerControl_ItemAdded), sender, e);
                return;
            }

            if (e.Smartpart is ISmartpart)
            {
                ISmartpart sp = e.Smartpart as ISmartpart;
                IDockingSmartpart dsp = e.Smartpart as IDockingSmartpart;
                Control c = e.Smartpart as Control;
                DockControl dc = e.Smartpart as DockControl;
                DockingUserControl duc = c as DockingUserControl;
                ModalDockingUserControl mduc = c as ModalDockingUserControl;
                ModalUserControl muc = c as ModalUserControl;

                if (dc == null)
                {
                    if (duc == null)
                    {
                        //encapsulate IDockingSmartpart
                        if (dsp != null && dsp.InitialAppearanceStyle == AppearanceStyle.Docked)
                        {
                            dc = new SBPweb.Controls.Windows.Docking.DockableWindow();
                        }
                        else
                        {
                            dc = new SBPweb.Controls.Windows.Docking.TabbedDocument();
                        }

                        dc.Size = c.Size;
                        dc.FloatingSize = c.Size;

                        dc.Controls.Add(c);
                        if (sp.ParentModule != null && sp.ParentModule.Icon != null)
                        {
                            dc.TabImage = sp.ParentModule.Icon.ToBitmap().GetThumbnailImage(16, 16, null, IntPtr.Zero);
                        }

                        dc.PersistState = true;
                        dc.Text = c.Text;

                        if (dsp != null)
                        {
                            dc.AllowClose = dsp.AllowClose;
                            dc.AllowCollapse = dsp.AllowCollapse;
                            dc.DockingRules.AllowDockBottom = dsp.AllowDockBottom;
                            dc.DockingRules.AllowTab = dsp.AllowDockCenter;
                            dc.DockingRules.AllowDockLeft = dsp.AllowDockLeft;
                            dc.DockingRules.AllowDockRight = dsp.AllowDockRight;
                            dc.DockingRules.AllowDockTop = dsp.AllowDockTop;
                            dc.DockingRules.AllowFloat = dsp.AllowFloat;
                            dc.Collapsed = dsp.Collapsed;
                            dc.CloseAction = dsp.HideOnlyWhenClose ? DockControlCloseAction.HideOnly : DockControlCloseAction.Dispose;
                            if (!string.IsNullOrEmpty(dsp.Caption))
                            {
                                dc.Text = dsp.Caption;
                            }
                        }
                    }
                    else
                    {
                        dc = duc.DockControlInstance as DockControl;
                    }

                    if (string.IsNullOrEmpty(c.Name))
                    {
                        c.Name = c.ToString();
                    }

                    dc.Name = "dc" + c.Name;

                }

                dc.Manager = pDockManager;
                //sp.IsVisible = sp.IsVisible;
                dc.DockSituationChanged -= new EventHandler(dc_DockSituationChanged);
                dc.DockSituationChanged += new EventHandler(dc_DockSituationChanged);

                if (!pDockControlDictionary.ContainsKey(e.Smartpart))
                {
                    pDockControlDictionary.Add(e.Smartpart, dc);
                }

                //
                // if ModalDockingUserControl added
                //
                if (mduc != null)
                {
                    if (!pModalSmartpartDictionary.ContainsKey(e.Smartpart.ParentModule.Name))
                    {
                        pModalSmartpartDictionary.Add(e.Smartpart.ParentModule.Name, e.Smartpart);
                    }
                    else
                    {
                        mduc.FireDisplayFailedEvent();
                        Remove(mduc);
                        return;
                    }

                    foreach (ISmartpart isp in sp.ParentModule.Smartparts)
                    {
                        if (isp != sp)
                        {
                            isp.IsEnabled = false;
                        }
                    }
                }

                //
                // if ModalUserControl added
                //
                if (muc != null)
                {
                    if (mModalUserControl != null)
                    {
                        muc.FireDisplayFailedEvent();
                        Remove(muc);
                        return;
                    }
                    else
                    {
                        mModalUserControl = muc;
                    }
                }

                if (muc != null)
                {
                    muc.ParentForm.ShowDialog(pDockManager.OwnerForm);
                }
                else if (mduc != null)
                {
                    dc.OpenFloating(WindowOpenMethod.OnScreenSelect);
                }
                else
                    if (sp.IsVisible)
                    {
                        if (dsp != null && dsp.InitialAppearanceStyle == AppearanceStyle.Float)
                        {
                            dc.OpenFloating(WindowOpenMethod.OnScreenActivate);
                        }
                        else if (dsp != null && dsp.InitialAppearanceStyle == AppearanceStyle.Tabbed)
                        {
                            dc.OpenDocked(ContainerDockLocation.Center, WindowOpenMethod.OnScreenActivate);
                        }
                        else if (dsp != null && duc != null && dsp.InitialAppearanceStyle == AppearanceStyle.Docked)
                        {
                            switch (duc.InitialDock)
                            {
                                case DockStyle.Left : 
                                    dc.OpenDocked(ContainerDockLocation.Left, WindowOpenMethod.OnScreenActivate);
                                    break;
                                case DockStyle.Top:
                                    dc.OpenDocked(ContainerDockLocation.Top, WindowOpenMethod.OnScreenActivate);
                                    break;
                                case DockStyle.Bottom:
                                    dc.OpenDocked(ContainerDockLocation.Bottom, WindowOpenMethod.OnScreenActivate);
                                    break;
                                default:
                                    dc.OpenDocked(ContainerDockLocation.Right, WindowOpenMethod.OnScreenActivate);
                                    break;
                            }
                        }
                        else
                        {
                            dc.Open(WindowOpenMethod.OnScreenActivate);
                        }
                    }
            }
        }

        protected void DockManagerControl_ItemRemoved(object sender, SmartpartEventArgs e)
        {
            if (e.Smartpart is ISmartpart)
            {
                if (pDockControlDictionary.ContainsKey(e.Smartpart))
                {
                    DockControl dc = pDockControlDictionary[e.Smartpart];

                    //It never happens normaly in this situation . and it can hide the main reason of error.
                    //if (dc.InvokeRequired)
                    //{
                    //    dc.Invoke(new EventHandler<SmartpartEventArgs>(DockManagerControl_ItemRemoved), sender, e);
                    //    return;
                    //}

                    //ModalDockingUserControl
                    if (e.Smartpart is ModalDockingUserControl)
                    {
                        if (e.Smartpart.ParentModule != null)
                        {
                            foreach (ISmartpart n in e.Smartpart.ParentModule.Smartparts)
                            {
                                n.IsEnabled = true;
                            }
                            if (pModalSmartpartDictionary.ContainsKey(e.Smartpart.ParentModule.Name))
                            {
                                pModalSmartpartDictionary.Remove(e.Smartpart.ParentModule.Name);
                            }
                        }
                    }

                    //ModalUserControl
                    if (e.Smartpart is ModalUserControl)
                    {
                        (e.Smartpart as ModalUserControl).ParentForm.Close();
                        mModalUserControl = null;
                    }

                    if (e.Smartpart is Control)
                    {
                        dc.Controls.Remove(e.Smartpart as Control);
                    }
                    if (dc.Controls.Count == 0 /*&& (dc.DockSituation == DockSituation.Document || dc.IsOpen || dc.DockSituation == DockSituation.Floating || dc.DockSituation == DockSituation.Docked || dc.DockSituation == DockSituation.None)*/)
                    {
						try
						{
							dc.Close();
							dc.Dispose();
						}
						catch (Exception ex)
						{
							mLoader.Host.LogManager.WriteError(this, "Cannot dispose dockcontrol: " + ex.ToString(), "General");
						}
                    }

                    pDockControlDictionary.Remove(e.Smartpart);
                }
            }
		}

		#endregion

		#region Windows Menu Handling

		private void dc_DockSituationChanged(object sender, EventArgs e)
		{
			DockControl dc = sender as DockControl;

			if (dc != null && dc.Tag is ToolStripMenuItem)
			{
				(dc.Tag as ToolStripMenuItem).Checked = DCIsOpen(dc);
			}
		}

        protected void pDockManager_DockControlRemoved(object sender, DockControlEventArgs e)
        {
			DockControl dc = e.DockControl as DockControl;
			if (dc != null)
			{
				if (pDisposingControls.Contains(dc))
				{
					pDisposingControls.Remove(dc);
				}
				ToolStripMenuItem mi = dc.Tag as ToolStripMenuItem;
				if (mi != null)
				{
					pWindowsMenuItem.DropDownItems.Remove(mi);
				}

				if (e.DockControl.Controls.Count > 0 && e.DockControl.Controls[0] is ISmartpart)
				{
					DockManagerControl_ItemRemoved(this, new SmartpartEventArgs(e.DockControl.Controls[0] as ISmartpart));
				}
			}
        }

        protected void pDockManager_DockControlAdded(object sender, DockControlEventArgs e)
        {
            DockControl dc = e.DockControl;
            IDockingSmartpart idsp = null;

			if (dc != null && dc.CloseAction == DockControlCloseAction.Dispose)
			{
				if (!pDisposingControls.Contains(dc))
				{
					pDisposingControls.Add(dc);
				}
				dc.PersistState = false;
			}
			else
			{
				if (pGuidPersistency.ContainsKey(dc.Name))
				{
					dc.Guid = new Guid(pGuidPersistency[dc.Name]);
				}
				else
				{
                    bool changed = false;
                    do
					{
						string guidstr = dc.Guid.ToString();
                        changed = false;
                        foreach (string guid in pGuidPersistency.Values)
						{
							if (guid == guidstr)
							{
								dc.Guid = new Guid();
								changed = true;
								break;
							}
						}
					} while (changed);
					pGuidPersistency.Add(dc.Name, dc.Guid.ToString());
				}
			}

            if (dc != null && dc.Controls != null && dc.Controls.Count > 0)
            {
                idsp = dc.Controls[0] as IDockingSmartpart;
            }

            if (dc.CloseAction == DockControlCloseAction.Dispose || (idsp != null && !idsp.IsShowInWindowMenu))
            {
                return;
            }

            if (idsp.IsShowInWindowMenu)
            {
                ToolStripMenuItem mi = new ToolStripMenuItem();
                mi.Text = dc.Text;
                mi.Tag = dc;
                mi.Click += new EventHandler(WindowsMenuItem_Click);
                dc.Tag = mi;
                pWindowsMenuItem.DropDownItems.Add(mi);

                dc.VisibleChanged -= new EventHandler(dc_VisibleChanged);
                dc.VisibleChanged += new EventHandler(dc_VisibleChanged);
            }
        }

        protected void dc_VisibleChanged(object sender, EventArgs e)
        {
            DockControl dc = sender as DockControl;
            if (dc.Tag is ToolStripMenuItem)
            {
                (dc.Tag as ToolStripMenuItem).Checked = DCIsOpen(dc);
            }
        }

        protected void WindowsMenuItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem mi = sender as ToolStripMenuItem;
            DockControl dc = mi.Tag as DockControl;
			ISmartpart sp = dc.Controls[0] as ISmartpart;
			if (sp != null)
			{
				sp.IsVisible = !mi.Checked;
			}
        }

        protected void tsmiShowAll_Click(object sender, EventArgs e)
        {
            foreach (DockControl dockControl in DockingManager.GetDockControls())
            {
                IDockingSmartpart idsp = null;
                if (dockControl != null && dockControl.Controls != null && dockControl.Controls.Count > 0)
                {
                    idsp = dockControl.Controls[0] as IDockingSmartpart;
                }

                if (!dockControl.IsOpen && (idsp != null && idsp.IsShowInWindowMenu))
                {
                    dockControl.Open();
                    foreach (Control c in dockControl.Controls)
                    {
                        c.Visible = true;
                    }
                    ToolStripMenuItem tsi = dockControl.Tag as ToolStripMenuItem;
                    if (tsi != null)
                    {
                        tsi.Checked = true;
                    }
                }
            }
        }

        protected void tsmiHideAll_Click(object sender, EventArgs e)
        {
            foreach (DockControl dockControl in DockingManager.GetDockControls())
            {
                IDockingSmartpart idsp = null;
                if (dockControl != null && dockControl.Controls != null && dockControl.Controls.Count > 0)
                {
                    idsp = dockControl.Controls[0] as IDockingSmartpart;
                }

                if (idsp != null && idsp.IsShowInWindowMenu)
                {
                    dockControl.Close();
                    ToolStripMenuItem tsi = dockControl.Tag as ToolStripMenuItem;
                    if (tsi != null)
                    {
                        tsi.Checked = false;
                    }
                }
            }
        }

        //private void ContextMenuService_Resize(object sender, ToolStripSizeChangeEventArgs e)
        //{
        //    pWindowMenuItem.Image = ContextMenuService.GetSizedImageFromIcon(Properties.Resources.Window, e.Size);
        //}

		#endregion

		#region Layout Menu Handling

		protected void tsmiSaveCurrent_Click(object sender, EventArgs e)
        {
			if (!string.IsNullOrEmpty(LayoutService.SelectedLayout))
			{
				LayoutService.SaveLayout(LayoutService.SelectedLayout);
			}
			else
			{
				tsmiSaveAs_Click(sender, e);
			}
        }

		protected void tsmiSaveAs_Click(object sender, EventArgs e)
		{
			string name = lnf.Execute(string.Empty);
			if (name != null)
			{
				bool doIt = true;
				if (LayoutService.LayoutGroup.Layouts.ContainsKey(name))
				{
					doIt = SBPweb.Controls.Windows.Common.MessageBox.Show("This layout already exists! Do you want to overwrite?", "Layout already exists", MessageBoxButtons.YesNo) == DialogResult.Yes;
				}
				if (doIt)
				{
					if (LayoutService.SaveLayout(name))
					{
						AddLayoutMenuItem(name);
						CheckLayoutMenuItem(name);
					}
				}
			}
		}

		protected void tsmiRename_Click(object sender, EventArgs e)
		{
			string oldName = LayoutService.SelectedLayout;
			if (!string.IsNullOrEmpty(oldName))
			{
				string newName = lnf.Execute(oldName);
				if (!string.IsNullOrEmpty(newName) && newName != oldName)
				{
					bool doIt = true;
					if (LayoutService.LayoutGroup.Layouts.ContainsKey(newName))
					{
						doIt = SBPweb.Controls.Windows.Common.MessageBox.Show("This layout already exists! Do you want to overwrite?", "Layout already exists", MessageBoxButtons.YesNo) == DialogResult.Yes;
					}
					if (doIt)
					{
						if (LayoutService.RenameLayout(oldName, newName))
						{
							DeleteLayoutMenuItem(oldName);
							AddLayoutMenuItem(newName);
							CheckLayoutMenuItem(newName);
						}
					}
				}
			}
		}

		protected void tsmiDelete_Click(object sender, EventArgs e)
		{
			string name = lsf.Execute(new List<string>(LayoutService.LayoutGroup.Layouts.Keys), null);
			if (!string.IsNullOrEmpty(name))
			{
				LayoutService.DeleteLayout(name);
				DeleteLayoutMenuItem(name);
			}
		}

		protected void newItem_Click(object sender, EventArgs e)
        {
            ToolStripMenuItem item = sender as ToolStripMenuItem;
			if (item != null && !item.Checked)
			{
				try
				{
					if (LayoutService.LayoutGroup.Layouts.ContainsKey(item.Name))
					{
						new SetLayoutProcHandler(SetLayoutProc).BeginInvoke(item.Name, null, new object());
						CheckLayoutMenuItem(item.Name);
					}
				}
				catch (Exception ex)
				{
					mLoader.Host.LogManager.WriteError(this, string.Format("Exception while setting layout ({0} - {1}", item.Name, ex.ToString()), "General");
					SBPweb.Controls.Windows.Common.MessageBox.Show("Could not load this layout", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
				}

			}
        }

        #endregion

		#region Layout Service events

		void LayoutService_LayoutLoading(object sender, EventArgs e)
		{
			foreach (DockControl dc in pDisposingControls)
			{
				dc.CloseAction = DockControlCloseAction.HideOnly;
			}
		}

		void LayoutService_LayoutLoaded(object sender, EventArgs e)
		{
			foreach (DockControl dc in pDisposingControls)
			{
				dc.CloseAction = DockControlCloseAction.Dispose;
				dc.Open();
			}
		}

		#endregion

		#region Loader Events

		void LayoutService_Initialized(object sender, EventArgs e)
		{

			#region Invoke into UI thread

			if (pDockManager.OwnerForm.InvokeRequired)
			{
				pDockManager.OwnerForm.Invoke(new EventHandler(LayoutService_Initialized), sender, e);
				return;
			}

			#endregion

			#region Create menuitems

			if (pLayoutsMenuItem == null)
			{
				pLayoutsMenuItem = new MenuItemControl();
				pLayoutsMenuItem.Name = "pLayoutsMenuItem";
				pLayoutsMenuItem.Text = LocalizationExtender.GetString("pLayoutsMenuItemText");
				pWindowMenuItem.DropDown.Items.Add(new ToolStripSeparator());
				pWindowMenuItem.DropDown.Items.Add(pLayoutsMenuItem);

				tsmiSaveCurrent = new MenuItemControl();
				tsmiSaveCurrent.Name = "tsmiSaveCurrent";
				tsmiSaveCurrent.Text = LocalizationExtender.GetString("tsmiSaveCurrentText");
				tsmiSaveCurrent.Click += new EventHandler(tsmiSaveCurrent_Click);

				tsmiSaveAs = new MenuItemControl();
				tsmiSaveAs.Name = "tsmiSaveAs";
				tsmiSaveAs.Text = LocalizationExtender.GetString("tsmiSaveAsText");
				tsmiSaveAs.Click += new EventHandler(tsmiSaveAs_Click);

				tsmiRename = new MenuItemControl();
				tsmiRename.Name = "tsmiRename";
				tsmiRename.Text = LocalizationExtender.GetString("tsmiRenameText");
				tsmiRename.Click += new EventHandler(tsmiRename_Click);

				tsmiDelete = new MenuItemControl();
				tsmiDelete.Name = "tsmiDelete";
				tsmiDelete.Text = LocalizationExtender.GetString("tsmiDeleteText");
				tsmiDelete.Click += new EventHandler(tsmiDelete_Click);

				tsmiSeparator = new ToolStripSeparator();
			}

			#endregion

			#region Loading layouts menuitems for modulegroup

			pLayoutsMenuItem.DropDown.Items.Clear();
			pLayoutsMenuItem.DropDown.Items.Add(tsmiSaveCurrent);
			pLayoutsMenuItem.DropDown.Items.Add(tsmiSaveAs);
			pLayoutsMenuItem.DropDown.Items.Add(tsmiRename);
			pLayoutsMenuItem.DropDown.Items.Add(tsmiDelete);
			pLayoutsMenuItem.DropDown.Items.Add(tsmiSeparator);
			tsmiSaveAs.Enabled = false;
			tsmiRename.Enabled = false;
			tsmiDelete.Enabled = false;
			tsmiSeparator.Visible = false;

			foreach (string name in LayoutService.LayoutGroup.Layouts.Keys)
			{
				AddLayoutMenuItem(name);
			}

			#endregion

			#region Applying default layout

			if (!string.IsNullOrEmpty(LayoutService.SelectedLayout) && LayoutService.LayoutGroup.Layouts.ContainsKey(LayoutService.SelectedLayout))
			{
				new SetLayoutProcHandler(SetLayoutProc).BeginInvoke(LayoutService.SelectedLayout, null, new object());
				CheckLayoutMenuItem(LayoutService.SelectedLayout);
			}

			#endregion

		}

		void LayoutService_Finalized(object sender, EventArgs e)
		{
			Finalize();
		}

		#endregion

		#region Localization

		private void LocalizationExtender_OnInvalidatingControls(object sender, EventArgs e)
		{
			pWindowMenuItem.Text = LocalizationExtender.GetString("pWindowMenuItemText");
			tsmiShowAll.Text = LocalizationExtender.GetString("tsmiShowAllText");
			tsmiHideAll.Text = LocalizationExtender.GetString("tsmiHideAllText");
			pWindowsMenuItem.Text = LocalizationExtender.GetString("pWindowsMenuItemText");
			if (LayoutService != null)
			{
				tsmiSaveCurrent.Text = LocalizationExtender.GetString("tsmiSaveCurrentText");
				tsmiSaveAs.Text = LocalizationExtender.GetString("tsmiSaveAsText");
				tsmiDelete.Text = LocalizationExtender.GetString("tsmiDeleteText");
				tsmiRename.Text = LocalizationExtender.GetString("tsmiRenameText");
				pLayoutsMenuItem.Text = LocalizationExtender.GetString("pLayoutsMenuItemText");
			}
		}

		#endregion

		#endregion

		#region Private helper methods

		#region Layout handler methods

		private delegate void SetLayoutProcHandler(string name);
		private void SetLayoutProc(string name)
		{
			if (pDockManager.OwnerForm.InvokeRequired)
			{
				pDockManager.OwnerForm.Invoke(new SetLayoutProcHandler(SetLayoutProc), name);
				return;
			}
			LayoutService.LoadLayout(name);
		}

		#endregion

		#region Layout menu handler methods

		private void SetSeparatorVisible(bool isVisible)
		{
			tsmiSeparator.Visible = isVisible;
			tsmiSaveAs.Enabled = (isVisible) && (!string.IsNullOrEmpty(LayoutService.SelectedLayout));
			tsmiRename.Enabled = (isVisible) && (!string.IsNullOrEmpty(LayoutService.SelectedLayout));
			tsmiDelete.Enabled = isVisible;
		}

		private void AddLayoutMenuItem(string name)
		{
			ToolStripMenuItem newItem = GetLayoutMenuItem(name);
			if (newItem == null)
			{
				newItem = new ToolStripMenuItem();
				newItem.Name = newItem.Text = name;
				newItem.Click += new EventHandler(newItem_Click);
				pLayoutsMenuItem.DropDown.Items.Add(newItem);
				SetSeparatorVisible(pLayoutsMenuItem.DropDown.Items.Count > 5);
			}
		}

		private void DeleteLayoutMenuItem(string name)
		{
			ToolStripMenuItem found = null;
			foreach (ToolStripItem i in pLayoutsMenuItem.DropDown.Items)
			{
				ToolStripMenuItem item = i as ToolStripMenuItem;
				if (item != null && item.Name == name)
				{
					found = item;
					break;
				}
			}
			if (found != null)
			{
				pLayoutsMenuItem.DropDown.Items.Remove(found);
				SetSeparatorVisible(pLayoutsMenuItem.DropDown.Items.Count > 5);
			}
		}

		private ToolStripMenuItem GetLayoutMenuItem(string name)
		{
			foreach (ToolStripItem i in pLayoutsMenuItem.DropDown.Items)
			{
				ToolStripMenuItem item = i as ToolStripMenuItem;
				if (item != null)
				{
					if (item.Name == name)
					{
						return item;
					}
				}
			}
			return null;
		}

		private void CheckLayoutMenuItem(string name)
		{
			foreach (ToolStripItem i in pLayoutsMenuItem.DropDown.Items)
			{
				ToolStripMenuItem item = i as ToolStripMenuItem;
				if (item != null)
				{
					if (item.Name == name)
					{
						item.Checked = true;
					}
					else
					{
						item.Checked = false;
					}
				}
			}
			SetSeparatorVisible(pLayoutsMenuItem.DropDown.Items.Count > 5);
		}

		#endregion

		protected bool DCIsOpen(DockControl dc)
		{
			return dc.DockSituation == DockSituation.Document || dc.DockSituation == DockSituation.Docked || dc.DockSituation == DockSituation.Floating;
		}

		#endregion

	}
}
